package ch.bfh.mobicomp.soda2.temperature;

import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.BatteryManager;
import android.os.IBinder;
import android.util.Log;
import ch.quantasy.android.repetitive.service.implementation.ARepetitiveService;

public class SODATemperatureDataCollectorService extends ARepetitiveService {
	public static final String TAG = "Temperature";
	public static final String SHARED_PREFERENCES = "ch.bfh.mobicomp.soda2.temperature.observer.SODATemperatureDataCollectorService.SharedPreferences";
	public static final String TEMPERATURE_STATUS_ACTION = "ch.bfh.mobicomp.soda2.temperature.observer.ObserverService.BATTERY_STATUS";
	public static final String TEMPERATURE_STATUS_ACTION_EXTRA_UPDATE_INTERVAL_IN_SECONDS = TEMPERATURE_STATUS_ACTION
			+ ".update interval in seconds";
	public static final String BATTERY_STATUS_EXTRA_TEMPERATURE = TEMPERATURE_STATUS_ACTION
			+ ".temperature";
	public static final String TEMPERATURE_STATUS_EXTRA_AT_TIME_IN_SECONDS = TEMPERATURE_STATUS_ACTION
			+ ".time in milli seconds";
	public static final String TEMPERATURE_JSON_REPRESENTATION="JSON";
	
	public static final String START_ACTION = "ch.bfh.mobicomp.soda2.temperature.observer.ObserverService.STARTED_ACTION";
	public static final String START_ACTION_EXTRA_AT_TIME_IN_MILLI_SECONDS = START_ACTION
			+ ".time in milli seconds";

	
	public static Intent getBatteryTemperatureIntent(Context context,
			int temperature, long atTimeInMilliSeconds) {
		// What shall be done
		Intent intent = new Intent(TEMPERATURE_STATUS_ACTION);
		// Who shall do it (explicitly)
		intent.setClass(context, SODATemperatureDataCollectorService.class);

		intent.putExtra(BATTERY_STATUS_EXTRA_TEMPERATURE, temperature);
		intent.putExtra(TEMPERATURE_STATUS_EXTRA_AT_TIME_IN_SECONDS,
				atTimeInMilliSeconds);
		return intent;
	}

	public static Intent getUpdateIntervalIntent(Context context,
			int timeInSeconds) {
		// What shall be done
		Intent intent = new Intent(TEMPERATURE_STATUS_ACTION);
		// Who shall do it (explicitly)
		intent.setClass(context, SODATemperatureDataCollectorService.class);
		intent.putExtra(TEMPERATURE_STATUS_ACTION_EXTRA_UPDATE_INTERVAL_IN_SECONDS,
				timeInSeconds);
		return intent;
	}

	public static Intent getStartIntent(Context context,
			long atTimeInMilliSeconds) {
		// What shall be done
		Intent intent = new Intent(START_ACTION);
		// Who shall do it (explicitly)
		intent.setClass(context, SODATemperatureDataCollectorService.class);
		intent.putExtra(START_ACTION_EXTRA_AT_TIME_IN_MILLI_SECONDS,
				atTimeInMilliSeconds);
		return intent;

	}

	public static String getSharedPreferencesName() {
		return SHARED_PREFERENCES;
	}

	private SharedPreferences sharedPreferences;

	@Override
	public void onCreate() {
		super.onCreate();
		sharedPreferences = getSharedPreferences(getSharedPreferencesName(),
				MODE_PRIVATE);

	}

	private void start(Intent intent) {
		Log.i(TAG, "Booted :" + intent);
		int updateIntervalInSeconds = sharedPreferences.getInt(
				TEMPERATURE_STATUS_ACTION_EXTRA_UPDATE_INTERVAL_IN_SECONDS, 10);
		super.setUpdateInterval(updateIntervalInSeconds, TimeUnit.SECONDS);
		ARepetitiveService.updateIntentStartStopRepetition(intent, true);
		Log.d(TAG, "Start");
	}

	private void changeUpdateIntervalInSeconds(Intent intent) {
		int updateIntervalInSeconds = intent.getExtras().getInt(
				TEMPERATURE_STATUS_ACTION_EXTRA_UPDATE_INTERVAL_IN_SECONDS);
		synchronized (sharedPreferences) {
			super.setUpdateInterval(updateIntervalInSeconds, TimeUnit.SECONDS);
			Editor editor = sharedPreferences.edit();
			editor.putInt(
					TEMPERATURE_STATUS_ACTION_EXTRA_UPDATE_INTERVAL_IN_SECONDS,
					updateIntervalInSeconds);
			editor.apply();
		}
	}

	private void getImmediateTemperatureStatusIntent() {
		Intent intent = this.registerReceiver(null, new IntentFilter(
				Intent.ACTION_BATTERY_CHANGED));
		int temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,
				0);
		Log.i(SODATemperatureDataCollectorService.TAG, "Temperature: "
				+ temperature);
		Intent serviceIntent = SODATemperatureDataCollectorService
				.getBatteryTemperatureIntent(this, temperature,
						System.currentTimeMillis());
		Log.i(SODATemperatureDataCollectorService.TAG,
				serviceIntent.getAction());
		startService(serviceIntent);
	}

	private void temperatureStatus(Intent intent) {
		int temperature = intent.getIntExtra(BATTERY_STATUS_EXTRA_TEMPERATURE,
				Integer.MIN_VALUE);
		temperature+=(int)(Math.random()*1000);
		long atTimeInMilliSeconds = intent.getLongExtra(
				TEMPERATURE_STATUS_EXTRA_AT_TIME_IN_SECONDS, 0);
		Log.i(TAG, "Battery temperature: " + temperature + " at:"
				+ atTimeInMilliSeconds);
		synchronized (sharedPreferences) {
			Editor editor = sharedPreferences.edit();
			editor.putInt(BATTERY_STATUS_EXTRA_TEMPERATURE, temperature);
			editor.putLong(TEMPERATURE_STATUS_EXTRA_AT_TIME_IN_SECONDS,
					atTimeInMilliSeconds);
			editor.putString(TEMPERATURE_JSON_REPRESENTATION, "TEM|T:"+temperature+"|@:"+atTimeInMilliSeconds);
			editor.apply();
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		// We do not care about that.
		return null;
	}

	@Override
	public int onStartCommand(final Intent intent, final int flags,
			final int startId) {
		Log.d(TAG, "Service Intent received: " + intent);
		if (intent == null || intent.getAction() == null) {
			return super.onStartCommand(intent, flags, startId);
		}
		Log.i(TAG, "Received :" + intent);

		if (intent.getAction().equals(
				SODATemperatureDataCollectorService.START_ACTION)) {
			start(intent);
		}
		if (intent.getAction().equals(
				SODATemperatureDataCollectorService.TEMPERATURE_STATUS_ACTION)) {
			if (intent.getExtras()
					.containsKey(BATTERY_STATUS_EXTRA_TEMPERATURE)) {
				temperatureStatus(intent);
			}
			if (intent.getExtras().containsKey(
					TEMPERATURE_STATUS_ACTION_EXTRA_UPDATE_INTERVAL_IN_SECONDS)) {
				changeUpdateIntervalInSeconds(intent);
			}
		}
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onStart(Intent intent) {
		getImmediateTemperatureStatusIntent();
	}

	@Override
	public void onRepeat() {
		getImmediateTemperatureStatusIntent();

	}

	@Override
	public void onStop() {
		// set Preferences to stopped...

	}

}
